API Authentication
This article explains how to authenticate with the Cyberhaven API using Python code examples.
Overview
Cyberhaven uses a two-step token-based authentication system:
- API Key: Long-lived credential (up to 1 year) created in the Console
- Access Token: Short-lived token (15 minutes) used for API requests
Why Authentication is Required
- Access Control: Only authorized users can access your data
- Security: Protects sensitive information like incidents and events
- Audit Trail: Tracks API usage for compliance
- Rate Limiting: Prevents abuse (max 5 concurrent requests per endpoint)
Creating an API Key
- Navigate to Settings > Users & API Keys in the Cyberhaven Console
- Click API Keys tab → New API Key
- Set name, role (e.g., "API Admin"), and validity period
- Important: Copy the key immediately - it won't be shown again
Python Implementation
Basic Authentication
import requests
from datetime import datetime, timedelta
class CyberhavenAPI:
def __init__(self, api_key, tenant):
# Store credentials and initialize token tracking
self.api_key = api_key
self.base_url = f"https://{tenant}"
self.access_token = None
self.token_expires = None
def get_access_token(self):
"""Exchange API key for a 15-minute access token"""
url = f"{self.base_url}/v2/auth/token/access"
payload = {"api_key": self.api_key}
response = requests.post(url, json=payload)
response.raise_for_status()
data = response.json()
self.access_token = data['access_token']
# Set expiry to 14 minutes to refresh before actual expiry
self.token_expires = datetime.now() + timedelta(minutes=14)
return self.access_token
def ensure_valid_token(self):
"""Check if token exists and hasn't expired, refresh if needed"""
if not self.access_token or datetime.now() >= self.token_expires:
self.get_access_token()
def make_request(self, method, endpoint, data=None):
"""Make authenticated API request with automatic token refresh"""
# Ensure we have a valid token before making the request
self.ensure_valid_token()
url = f"{self.base_url}{endpoint}"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}
response = requests.request(method, url, headers=headers, json=data)
response.raise_for_status()
return response.json()
# Usage example
api = CyberhavenAPI(
api_key="your_api_key_here",
tenant="your-tenant-name.cyberhaven.io"
)
# Get incidents - token will be automatically obtained
incidents = api.make_request("GET", "/v2/incidents")
print(f"Found {len(incidents.get('incidents', []))} incidents")
curl Example
# Step 1: Get access token
API_KEY="your_api_key_here"
TENANT="your-tenant-name.cyberhaven.io"
ACCESS_TOKEN=$(curl -s -X POST \
"https://${TENANT}/v2/auth/token/access" \
-H "Content-Type: application/json" \
-d "{\"api_key\": \"${API_KEY}\"}" | \
jq -r '.access_token')
# Step 2: Use token for API calls
curl -X GET \
"https://${TENANT}/v2/incidents" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json"
Advanced Python with Error Handling
import requests
import time
from datetime import datetime, timedelta
class CyberhavenAPI:
def __init__(self, api_key, tenant, max_retries=3):
self.api_key = api_key
self.base_url = f"https://{tenant}"
self.access_token = None
self.token_expires = None
self.max_retries = max_retries
def get_access_token(self):
"""Get access token with error handling"""
url = f"{self.base_url}/v2/auth/token/access"
payload = {"api_key": self.api_key}
try:
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()
data = response.json()
self.access_token = data['access_token']
self.token_expires = datetime.now() + timedelta(minutes=14)
return self.access_token
except requests.exceptions.RequestException as e:
raise Exception(f"Authentication failed: {e}")
def make_request(self, method, endpoint, data=None):
"""Make request with retry logic and automatic token refresh"""
for attempt in range(self.max_retries):
try:
# Refresh token if needed
if not self.access_token or datetime.now() >= self.token_expires:
self.get_access_token()
url = f"{self.base_url}{endpoint}"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Content-Type": "application/json"
}
response = requests.request(method, url, headers=headers, json=data, timeout=60)
# Handle token expiry
if response.status_code == 401:
self.access_token = None # Force token refresh
continue
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
if attempt == self.max_retries - 1:
raise Exception(f"Request failed after {self.max_retries} attempts: {e}")
time.sleep(2 ** attempt) # Exponential backoff
# Usage with error handling
try:
api = CyberhavenAPI("your_api_key", "your-tenant.cyberhaven.io")
incidents = api.make_request("GET", "/v2/incidents")
print(f"Success: {len(incidents.get('incidents', []))} incidents")
except Exception as e:
print(f"Error: {e}")
Key Points
- Token Expiry: Access tokens expire in 15 minutes
- Rate Limits: Maximum 5 concurrent requests per endpoint
- Security: Store API keys securely (environment variables)
- Error Handling: Always handle 401 (unauthorized) and 429 (rate limit) responses
- Testing: Use the API explorer in Administration > API Specification